package com.biz.ssm.conf;

import com.biz.ssm.security.JWTAuthenticationFilter;
import com.biz.ssm.security.MyLoginUrlAuthenticationEntryPoint;
import com.biz.ssm.security.MyUserDetailService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.core.GrantedAuthorityDefaults;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.web.cors.CorsUtils;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	// @see SecurityExpressionRoot
	private final String defaultRolePrefix = "";

	@Bean("grantedAuthorityDefaults")
	GrantedAuthorityDefaults grantedAuthorityDefaults() {
		return new GrantedAuthorityDefaults(defaultRolePrefix);
	}

	@Bean(name = "securityExpressionHandler")
	SecurityExpressionHandler<FilterInvocation> securityExpressionHandler() {
		DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
		defaultWebSecurityExpressionHandler.setDefaultRolePrefix(defaultRolePrefix);
		return defaultWebSecurityExpressionHandler;
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
				// 静态资源和一些所有人都能访问的请求
				.antMatchers("/**").permitAll()
				.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()    //对preflight放行
				// 登录
				.and().formLogin().disable().sessionManagement().disable()
				// session管理
				.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
				.and().csrf().disable().headers().frameOptions().disable()
				.and().cors()
				.and().exceptionHandling().authenticationEntryPoint(new MyLoginUrlAuthenticationEntryPoint("/notLogin"))
		;
	    http.addFilter(new JWTAuthenticationFilter(authenticationManager()));
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(new MyUserDetailService()).passwordEncoder(new BCryptPasswordEncoder());
	}
}
